#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <unistd.h>
#include "InetAddr.hpp"

class Reactor;
class Connection;
using handler_t = std::function<void(Connection*)>;

#define NormalConnection 1
#define ListenConnection 2

class Connection {
private:
    static const int gdefaultsockfd = -1;

public:
    Connection(int sockfd, Reactor* R, InetAdrr addr) 
        : _sockfd(sockfd),
          _R(R),
          _addr(addr) 
    {}

    int Sockfd() {
        return _sockfd;
    }

    void AddHanlder(handler_t recver, handler_t sender, handler_t excepter) {
        _handler_recver = recver;
        _handler_sender = sender;
        _handler_excepter = excepter;
    }

    std::string& GetInbuff() {
        return _inbuff;
    }

    std::string& GetOutbuff() {
        return  _outbuff;
    }

    void CloseSock() {
        close(_sockfd);
        _sockfd = gdefaultsockfd;
    }

    void AppendInbuff(const std::string& add) {
        _inbuff += add;
    }

    void AppendOutbuff(const std::string& add) {
        _outbuff += add;
    }

    void DecreaseOutbuff(int n) {
        _outbuff.erase(0, n);
    }

    void SetEvents(uint32_t events) {
        _events = events;
    }

    uint32_t  GetEvents() {
        return _events;
    }

    ~Connection() {
        if (_sockfd > 0) 
            close(_sockfd);
    }
private:
    int _sockfd;
    uint32_t _events;
    std::string _inbuff;
    std::string _outbuff;
public:
    handler_t _handler_recver;
    handler_t _handler_sender;
    handler_t _handler_excepter;
    Reactor* _R;
    InetAdrr _addr;
};